/* 
 * File:   Point.h
 * Author: Muhammad Anis
 *
 * Created on October 31, 2012, 9:29 PM
 */

#include <iostream>
#include <sstream>
#include "../BaseElementCal/BaseElementCal.h"
using namespace  std;

#ifndef POINT_H
#define	POINT_H

template <class T>

class Point : BaseElementCal{
private :
    T absis;
    T ordinat;
public:
    /*
     * Default Konstruktor
     */
    Point();
    /**
     * Custom Konstruktor
     */
    Point(T x,T y);
    /*
     * Copy Constructor
     */
    Point(const Point& p);
    /*
     * Destruktor
     */
    ~Point();
    
    /**
     * Operator =
     */
    Point& operator=(const Point&);
    
    bool operator<(const Point&);
    
    bool operator==(const Point&);
    
    void PrintPoint();
    
    void Move(T x, T y);
    
    bool IsOrigin();
    
    Point MirrorOf();
    
    void Mirror();
    
    string toString();
    
    
    /**
     * Getter Setter
     */
    

    T GetAbsis() const {
        return absis;
    }

    T GetOrdinat() const {
        return ordinat;
    }

    void SetAbsis(T absis) {
        this->absis = absis;
    }

    void SetOrdinat(T ordinat) {
        this->ordinat = ordinat;
    }
};

template <class T>

Point<T>::Point(){
    this->absis = 0;
    this->ordinat = 0;
}

template <class T>
Point<T>::Point(T x, T y){
    this->absis = x;
    this->ordinat = y;
}

template <class T>
Point<T>::Point(const Point& p){
    this->absis = p.GetAbsis();
    this->ordinat = p.GetOrdinat();
}

template <class T>
Point<T>::~Point(){
    
}

template <class T>
Point<T>& Point<T>::operator=(const Point& p){
    this->absis = p.absis;
    this->ordinat = p.ordinat;
    return *this;
}

template <class T>
bool Point<T>::operator <(const Point& p){
    return (this->absis < p.absis && this->ordinat < p.ordinat );
}

template <class T>
bool Point<T>::operator ==(const Point& p){
    return (this->absis== p.absis && this->ordinat==p.ordinat);
}

template <class T>
void Point<T>::PrintPoint(){
    cout<<"Absis :"<<this->absis<<" Ordinat: "<<this->ordinat<<endl;
}

template <class T>
void Point<T>::Move(T x, T y){
    this->absis+=x;
    this->ordinat+=y;
}

template <class T>
bool Point<T>::IsOrigin(){
    return this->absis==0 && this->ordinat==0;
}

template <class T>
Point<T> Point<T>::MirrorOf(){
    Point p;
    p.absis = -this->absis;
    p.ordinat = -this->ordinat;
    return p;
}

template <class T>
void Point<T>::Mirror(){
    this->absis = -this->absis;
    this->ordinat = -this->ordinat;
}

template <class T>
string Point<T>::toString(){
    string s;
    ostringstream oss;
    oss<<this->absis;
    s+=oss.str();
    s+=",";
    oss<<this->ordinat;
    s+=oss.str();
    return s;
}

#endif	/* POINT_H */
